home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Graphics⁄Sound / RTrace-1.0-src / shade.c < prev    next >
Text File  |  1992-08-17  |  5KB  |  166 lines

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *  Paul Strauss        - shading model
  11.  *  Craig Kolb          - textures
  12.  *  David Buck          - textures
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted
  15.  * provided that the above copyright notice and this paragraph are
  16.  * duplicated in all such forms and that any documentation,
  17.  * advertising materials, and other materials related to such
  18.  * distribution and use acknowledge that the software was developed
  19.  * by Antonio Costa, at INESC-Norte. The name of the author and
  20.  * INESC-Norte may not be used to endorse or promote products derived
  21.  * from this software without specific prior written permission.
  22.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  23.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  24.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25.  */
  26. #include "defs.h"
  27. #include "extern.h"
  28.  
  29. /**********************************************************************
  30.  *    RAY TRACING - Shade - Version 7.0                               *
  31.  *                                                                    *
  32.  *    MADE BY    : Antonio Costa, INESC-Norte, October 1988           *
  33.  *    ADAPTED BY : Antonio Costa, INESC-Norte, June 1989              *
  34.  *    MODIFIED BY: Antonio Costa, INESC-Norte, October 1991           *
  35.  **********************************************************************/
  36.  
  37. /***** Shading *****/
  38. boolean
  39. refract(ray, normal, inside, refraction)
  40.   ray_ptr         ray;
  41.   xyz_ptr         normal;
  42.   boolean         inside;
  43.   real            refraction;
  44. {
  45.   REG real        k0, k1, ratio;
  46.  
  47.   k0 = -DOT_PRODUCT(ray->vector, *normal);      /* Incidence angle cosine */
  48.   if (ABS(k0) < ROUNDOFF)
  49.     return FALSE;
  50.   if (inside)
  51.     ratio = refraction;         /* Leaving object */
  52.   else
  53.     ratio = 1.0 / refraction;   /* Entering object */
  54.   k1 = 1.0 - SQR(ratio) * (1.0 - SQR(k0));
  55.   if (k1 >= ROUNDOFF)
  56.   {
  57.     k1 = ratio * k0 - SQRT(k1);
  58.     /* Refracted ray */
  59.     ray->vector.x = ratio * ray->vector.x + k1 * normal->x;
  60.     ray->vector.y = ratio * ray->vector.y + k1 * normal->y;
  61.     ray->vector.z = ratio * ray->vector.z + k1 * normal->z;
  62.     return TRUE;
  63.   }
  64.   return FALSE;
  65. }
  66. void
  67. make_diffuse_vector(normal, result)
  68.   xyz_ptr         normal, result;
  69. {
  70.   real            a1, sin_a1_sin_a2, cos_a1_sin_a2, sin_a2, cos_a2;
  71.   xyz_struct      u, v;
  72.  
  73.   cos_a2 = SQRT(RANDOM);
  74.   sin_a2 = SQRT(1.0 - SQR(cos_a2));
  75.   a1 = 2 * PI * RANDOM;
  76.   sin_a1_sin_a2 = SIN(a1) * sin_a2;
  77.   cos_a1_sin_a2 = COS(a1) * sin_a2;
  78.   v.x = 1.0;
  79.   v.y = 0.0;
  80.   v.z = 0.0;
  81.   if (ABS(DOT_PRODUCT(*normal, v)) > 1.0 - ROUNDOFF)
  82.   {
  83.     v.y = 1.0;
  84.     v.x = 0.0;
  85.   }
  86.   CROSS_PRODUCT(u, *normal, v);
  87.   NORMALIZE(u);
  88.   CROSS_PRODUCT(v, u, *normal);
  89.   result->x = u.x * cos_a1_sin_a2 + v.x * sin_a1_sin_a2 + normal->x * cos_a2;
  90.   result->y = u.y * cos_a1_sin_a2 + v.y * sin_a1_sin_a2 + normal->y * cos_a2;
  91.   result->z = u.z * cos_a1_sin_a2 + v.z * sin_a1_sin_a2 + normal->z * cos_a2;
  92.   NORMALIZE(*result);
  93. }
  94. void
  95. make_specular_vector(reflected, normal, factor, result)
  96.   xyz_ptr         reflected, normal, result;
  97.   real            factor;
  98. {
  99.   real            a1, sin_a1_sin_a2, cos_a1_sin_a2, sin_a2, cos_a2;
  100.   xyz_struct      u, v;
  101.  
  102.   do
  103.   {
  104.     cos_a2 = POWER(SQRT(RANDOM), factor + 1.0);
  105.     sin_a2 = SQRT(1.0 - SQR(cos_a2));
  106.     a1 = 2 * PI * RANDOM;
  107.     sin_a1_sin_a2 = SIN(a1) * sin_a2;
  108.     cos_a1_sin_a2 = COS(a1) * sin_a2;
  109.     v.x = 1.0;
  110.     v.y = 0.0;
  111.     v.z = 0.0;
  112.     if (ABS(DOT_PRODUCT(*reflected, v)) > 1.0 - ROUNDOFF)
  113.     {
  114.       v.y = 1.0;
  115.       v.x = 0.0;
  116.     }
  117.     CROSS_PRODUCT(u, *reflected, v);
  118.     NORMALIZE(u);
  119.     CROSS_PRODUCT(v, u, *reflected);
  120.     result->x = u.x * cos_a1_sin_a2 + v.x * sin_a1_sin_a2 +
  121.       reflected->x * cos_a2;
  122.     result->y = u.y * cos_a1_sin_a2 + v.y * sin_a1_sin_a2 +
  123.       reflected->y * cos_a2;
  124.     result->z = u.z * cos_a1_sin_a2 + v.z * sin_a1_sin_a2 +
  125.       reflected->z * cos_a2;
  126.     NORMALIZE(*result);
  127.   } while (DOT_PRODUCT(*result, *normal) < ROUNDOFF);
  128. }
  129. int
  130. estimate_diffuse(n, d)
  131.   int             n;
  132.   real            d;
  133. {
  134.    return ROUND((real) n * d);
  135. }
  136. int
  137. estimate_specular(n, s, f)
  138.   int             n;
  139.   real            s, f;
  140. {
  141. #define S_THRESHOLD (0.5)
  142.   if (s < S_THRESHOLD)
  143.     return ROUND((real) n * s);
  144.   else
  145.     return ROUND((real) n / (1.0 + f) * (s + f / (1.0 - S_THRESHOLD) *
  146.                                          (S_THRESHOLD - S_THRESHOLD * s))); 
  147. #undef S_THRESHOLD
  148. }
  149. void
  150. shade(position, normal, ray, object, color)
  151.   xyz_ptr         position, normal;     /* Normal may be modified */
  152.   ray_ptr         ray;
  153.   object_ptr      object;
  154.   rgb_ptr         color;
  155. {
  156.   switch (shade_mode)
  157.   {
  158.   case 0:
  159.     shade_phong(position, normal, ray, object, color);
  160.     break;
  161.   case 1:
  162.     shade_strauss(position, normal, ray, object, color);
  163.     break;
  164.   }
  165. }
  166.